/**
 * ChatParser - 聊天解析器
 * 
 * 负责解析用户输入的聊天记录，识别发言者和消息内容
 * Requirements: 5.1, 5.2, 5.3, 5.4
 */

import type { ChatMessage, ParsedChat, ValidationResult, EmotionalTone } from '../types';

/**
 * 聊天解析结果
 */
export interface ChatParseResult {
  success: boolean;
  data?: ParsedChat;
  error?: string;
}

/**
 * 聊天解析器类
 */
export class ChatParser {
  // 常见的聊天记录格式正则表达式
  // 格式1: "发送者: 消息内容" 或 "发送者：消息内容"
  private static readonly PATTERN_COLON = /^(.+?)[：:]\s*(.+)$/;
  
  // 格式2: "[发送者] 消息内容"
  private static readonly PATTERN_BRACKET = /^\[(.+?)\]\s*(.+)$/;
  
  // 格式3: "发送者 说: 消息内容" 或 "发送者 说：消息内容"
  private static readonly PATTERN_SAY = /^(.+?)\s+说[：:]\s*(.+)$/;

  /**
   * 验证输入文本
   * @param rawText 原始聊天文本
   * @returns 验证结果
   */
  validate(rawText: string): ValidationResult {
    // 检查空白输入
    if (!rawText || rawText.trim().length === 0) {
      return {
        valid: false,
        error: '请输入聊天记录'
      };
    }

    // 检查是否有可解析的内容
    const lines = rawText.split('\n').filter(line => line.trim().length > 0);
    if (lines.length === 0) {
      return {
        valid: false,
        error: '请输入聊天记录'
      };
    }

    return { valid: true };
  }

  /**
   * 解析聊天文本
   * @param rawText 原始聊天文本
   * @returns 解析结果
   */
  parse(rawText: string): ChatParseResult {
    // 先验证输入
    const validation = this.validate(rawText);
    if (!validation.valid) {
      return {
        success: false,
        error: validation.error
      };
    }

    const lines = rawText.split('\n').filter(line => line.trim().length > 0);
    const messages: ChatMessage[] = [];
    const participantSet = new Set<string>();

    // 尝试解析每一行
    for (const line of lines) {
      const trimmedLine = line.trim();
      const parsed = this.parseLine(trimmedLine);
      
      if (parsed) {
        messages.push(parsed);
        participantSet.add(parsed.sender);
      } else {
        // 如果无法解析，尝试作为上一条消息的续行
        if (messages.length > 0) {
          const lastMessage = messages[messages.length - 1];
          lastMessage.content += '\n' + trimmedLine;
        } else {
          // 第一行无法解析，尝试智能解析
          // 假设整段文本是单人消息
          messages.push({
            sender: '未知',
            content: trimmedLine,
            isUser: false
          });
          participantSet.add('未知');
        }
      }
    }

    // 如果没有解析出任何消息，返回错误
    if (messages.length === 0) {
      return {
        success: false,
        error: '无法解析聊天记录格式，请检查输入'
      };
    }

    // 确定情感基调（简单实现，后续可通过 LLM 增强）
    const emotionalTone = this.detectEmotionalTone(messages);

    // 标记用户消息
    const participants = Array.from(participantSet);
    
    // 策略1：如果发送者是"我"，直接标记为用户消息
    // 策略2：如果没有"我"，则最后一条消息的发送者是对方（用户需要回复的人）
    const hasMe = participants.includes('我');
    
    if (hasMe) {
      // 有明确的"我"标记，直接使用
      messages.forEach(msg => {
        msg.isUser = msg.sender === '我';
      });
    } else if (participants.length >= 2 && messages.length > 0) {
      // 没有"我"标记，使用位置推断
      // 最后发言的人是对方，用户需要回复他
      const lastSender = messages[messages.length - 1].sender;
      messages.forEach(msg => {
        msg.isUser = msg.sender !== lastSender;
      });
    } else if (participants.length === 1) {
      // 只有一个参与者，假设都是对方的消息
      messages.forEach(msg => {
        msg.isUser = false;
      });
    }

    return {
      success: true,
      data: {
        messages,
        participants,
        emotionalTone
      }
    };
  }

  /**
   * 解析单行消息
   * @param line 单行文本
   * @returns 解析出的消息，或 null
   */
  private parseLine(line: string): ChatMessage | null {
    // 尝试各种格式
    let match: RegExpMatchArray | null;

    // 格式1: "发送者: 消息内容"
    match = line.match(ChatParser.PATTERN_COLON);
    if (match && match[1].length <= 20) { // 发送者名称不应太长
      return {
        sender: match[1].trim(),
        content: match[2].trim(),
        isUser: false
      };
    }

    // 格式2: "[发送者] 消息内容"
    match = line.match(ChatParser.PATTERN_BRACKET);
    if (match) {
      return {
        sender: match[1].trim(),
        content: match[2].trim(),
        isUser: false
      };
    }

    // 格式3: "发送者 说: 消息内容"
    match = line.match(ChatParser.PATTERN_SAY);
    if (match) {
      return {
        sender: match[1].trim(),
        content: match[2].trim(),
        isUser: false
      };
    }

    return null;
  }

  /**
   * 检测情感基调
   * @param messages 消息列表
   * @returns 情感基调
   */
  private detectEmotionalTone(messages: ChatMessage[]): EmotionalTone {
    const allContent = messages.map(m => m.content).join(' ');
    
    // 简单的关键词匹配（后续可通过 LLM 增强）
    const happyKeywords = ['开心', '高兴', '太好了', '哈哈', '😄', '😊', '🎉', '棒', '赞'];
    const sadKeywords = ['难过', '伤心', '哭', '😢', '😭', '唉', '失望'];
    const comfortKeywords = ['没关系', '别担心', '会好的', '加油', '支持你'];
    const funnyKeywords = ['哈哈哈', '笑死', '🤣', '😂', '搞笑', '有趣'];
    const gratefulKeywords = ['谢谢', '感谢', '多谢', '感激', '🙏'];
    const apologeticKeywords = ['对不起', '抱歉', '不好意思', 'sorry', '我错了'];

    const checkKeywords = (keywords: string[]) => 
      keywords.some(kw => allContent.includes(kw));

    if (checkKeywords(happyKeywords)) return 'happy';
    if (checkKeywords(sadKeywords)) return 'sad';
    if (checkKeywords(comfortKeywords)) return 'comfort';
    if (checkKeywords(funnyKeywords)) return 'funny';
    if (checkKeywords(gratefulKeywords)) return 'grateful';
    if (checkKeywords(apologeticKeywords)) return 'apologetic';

    return 'neutral';
  }


  /**
   * 将解析后的聊天记录格式化为标准文本格式
   * @param chat 解析后的聊天记录
   * @returns 格式化后的文本
   */
  format(chat: ParsedChat): string {
    if (!chat || !chat.messages || chat.messages.length === 0) {
      return '';
    }

    return chat.messages
      .map(msg => `${msg.sender}: ${msg.content}`)
      .join('\n');
  }

  /**
   * 检查两个 ParsedChat 是否等价
   * 用于往返一致性测试
   * @param a 第一个聊天记录
   * @param b 第二个聊天记录
   * @returns 是否等价
   */
  static isEquivalent(a: ParsedChat, b: ParsedChat): boolean {
    if (a.messages.length !== b.messages.length) {
      return false;
    }

    for (let i = 0; i < a.messages.length; i++) {
      const msgA = a.messages[i];
      const msgB = b.messages[i];
      
      if (msgA.sender !== msgB.sender || msgA.content !== msgB.content) {
        return false;
      }
    }

    // 检查参与者（顺序可能不同，所以用 Set 比较）
    const participantsA = new Set(a.participants);
    const participantsB = new Set(b.participants);
    
    if (participantsA.size !== participantsB.size) {
      return false;
    }

    for (const p of participantsA) {
      if (!participantsB.has(p)) {
        return false;
      }
    }

    return true;
  }
}

// 导出单例实例
export const chatParser = new ChatParser();
